#include "../common/config.h"
#include "fsconference.h"

#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>

extern int gRunThread;
extern LoggerPtr gLogger;
void * APR_THREAD_FUNC fetch_order(apr_thread_t *thd, void *data)
{
retry:

    try
    {

        sql::Connection *con = GetDBC();
        sql::PreparedStatement *stmtup, *stmt;
        sql::ResultSet *res;

        if (con != NULL)
        {
            LOG4CXX_INFO(gLogger, "get database connect  success");
        }
        else
        {
            LOG4CXX_WARN(gLogger, "get database connect  failed");
        }

        stmt = con->prepareStatement("select id,acct,caller,called,passwd  from conference where conference.result = '0' and calltime<=now() order by id asc");
        stmtup = con -> prepareStatement ("update conference set result='process',calltime=now() where id>=(?) and id<=(?)");

        while (gRunThread)
        {
            //res = stmt->executeQuery("select id,acct,caller,called  from ordercall where ordercall.result = '0' and calltime<=now() order by id asc");
            res = stmt->executeQuery();
            string startid = "-1", endid = "-1";

            while (res->next())
            {
                conference_info_t* pNewJob = new conference_info_t();
                pNewJob->id = res->getString(1);
                pNewJob->acct = res->getString(2);
                pNewJob->caller = res->getString(3);
                pNewJob->called = res->getString(4);
                pNewJob->passwd = res->getString(5);

                if (strcmp(startid.c_str(), "-1") == 0)
                {
                    startid = pNewJob->id;
                }

                endid = pNewJob->id;
                LOG4CXX_TRACE(gLogger, "get conference job id=" << pNewJob->id << "acct= " << pNewJob->acct << " caller=" << pNewJob->caller << " called=" << pNewJob->called);
                apr_queue_push(jobqueue, pNewJob);
            }

            delete res;

            if (strcmp(startid.c_str(), "-1") != 0)
            {
                stmtup -> setString (1, startid.c_str());
                stmtup -> setString (2, endid.c_str());
                stmtup -> executeUpdate();
            }

            apr_sleep(100000);
        }

        delete stmtup;
        delete stmt;
        ReleaseDBC(con);
    }
    catch (sql::SQLException &e)
    {
        LOG4CXX_WARN(gLogger, "err:" << e.what() << " (MySQL error code: " << e.getErrorCode() << ", SQLState: " << e.getSQLState());
        goto retry;
    }

    return 0;
}

void * APR_THREAD_FUNC result_order(apr_thread_t *thd, void *data)
{
retry_result:

    try
    {

        sql::Connection *con = GetDBC();

        if (con != NULL)
        {
            LOG4CXX_INFO(gLogger, "get database connect  success");
        }
        else
        {
            LOG4CXX_WARN(gLogger, "get database connect  failed");
        }


        sql::Statement *stmt = con->createStatement();

        while (gRunThread)
        {
            conference_info_t* pJob = NULL;

            while (apr_queue_pop (resultqueue, (void**)&pJob) == APR_SUCCESS)
            {
                stmt->execute(("UPDATE conference SET calltime=now(),conference.result='" + pJob->result + "' where id=" + pJob->id).c_str());
                delete pJob;
                pJob = NULL;
            }
        }

        delete stmt;
        ReleaseDBC(con);
    }
    catch (sql::SQLException &e)
    {
        LOG4CXX_WARN(gLogger, "err:" << e.what() << " (MySQL error code: " << e.getErrorCode() << ", SQLState: " << e.getSQLState());
        goto retry_result;
    }

    return 0;
}
